<!DOCTYPE html>
<html>
<head>
<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
<script src="../domui/js/cr.js"></script>
<script src="../domui/js/cr/event_target.js"></script>
<script src="plugin_settings.js" type="text/javascript"></script>
<script>
goog.require('goog.testing.jsunit');
</script>
<script src="chrome_stubs.js" type="text/javascript"></script>
</head>
<body>
<script>
function testConstruction() {
  var settings = createSettings();
}

function testSet() {
  var settings = createSettings();
  var rules = {
    'http://example.com/*': 'block',
    'http://google.com/*': 'allow',
    'http://moose.org/*': 'allow',
  };
  var numCallbacks = 0;
  for (var pattern in rules) {
    settings.set(pattern, rules[pattern], function(error) {
      numCallbacks++;
      assertUndefined(error);
    });
  }
  assertEquals(Object.keys(rules).length, numCallbacks);
  assertObjectEquals(rules, _rules);
}

function testSetInvalid() {
  var settings = createSettings();
  // Attempting to set an invalid pattern should return an error in the
  // callback.
  var callbackCalled = false;
  settings.set('__invalid_pattern', 'block', function(error) {
    callbackCalled = true;
    assertEquals('Invalid pattern', error);
  });
  assertTrue(callbackCalled);
  assertObjectEquals({}, _rules);

  // Attempting to set an invalid setting should immediately throw an exception.
  callbackCalled = false;
  assertThrows(function() {
    settings.set('http://example.com/*', '__invalid_setting', function() {
      callbackCalled = true;
    });
  });
  assertFalse(callbackCalled);
  assertObjectEquals({}, _rules);
}

function testGet() {
  var rules = {
    'http://example.com/*': 'block',
    'http://google.com/*': 'allow',
    'http://moose.org/*': 'allow',
  };
  var settings = createSettings(rules);
  for (var pattern in rules)
    assertEquals(rules[pattern], settings.get(pattern));
}

function testGetAll() {
  var settings = createSettings({
    'http://example.com/*': 'block',
    'http://google.com/*': 'allow',
    'http://moose.org/*': 'allow',
  });
  var rules = settings.getAll();
  // Sort the rules lexicographically by their pattern.
  rules.sort(function(a, b) {
    if (a.primaryPattern == b.primaryPattern) {
      return 0;
    }
    if (a.primaryPattern > b.primaryPattern) {
      return 1;
    }
    return -1;
  });
  assertEquals(3, rules.length);
  assertObjectEquals({'primaryPattern': 'http://example.com/*',
                      'setting': 'block'},
                     rules[0]);
  assertObjectEquals({'primaryPattern': 'http://google.com/*',
                      'setting': 'allow'},
                     rules[1]);
  assertObjectEquals({'primaryPattern': 'http://moose.org/*',
                      'setting': 'allow'},
                     rules[2]);
}

function testUpdate() {
  var settings = createSettings({
    'http://example.com/*': 'block',
    'http://google.com/*': 'allow',
    'http://moose.org/*': 'allow',
  });
  var numCallbacks = 0;
  settings.update('http://google.com/*', 'http://google.com/*', 'ask',
                  function(error) {
    numCallbacks++;
    assertUndefined(error);
  });
  assertEquals('ask', _rules['http://google.com/*']);

  settings.update('http://google.com/*', 'http://blurp.net/*', 'ask',
                  function(error) {
    numCallbacks++;
    assertUndefined(error);
  });
  assertUndefined(_rules['http://google.com/*']);
  assertEquals('ask', _rules['http://blurp.net/*']);

  // Attempting to update a rule to an invalid pattern should return an error
  // and leave the rules unchanged.
  settings.update('http://example.com/*', '__invalid_pattern', 'ask',
                  function(error) {
    numCallbacks++;
    assertEquals('Invalid pattern', error);
  });
  assertUndefined(_rules['__invalid_pattern']);
  assertEquals('block', _rules['http://example.com/*']);

  assertEquals(3, numCallbacks);
}

function tearDown() {
  // Clear local storage and |rules_| to make sure no state leaks into the next
  // test.
  window.localStorage.clear();
  _rules = {};
}
</script>
</body>
</html>
